import { Provide } from '@midwayjs/decorator';
import { fork } from 'child_process';
import { IUserOptions } from '../interface';

let rooms: Object
rooms = {}

@Provide()
export class UserService {


  constructor() {
  }

  async getUser(options: IUserOptions) {
    return {
      uid: options.uid,
      username: 'mockedName',
      phone: '12345678901',
      email: 'xxx.xxx@xxx.com',
    };
  }

  //删除房间
  private _DeleteRoom(rid: string) {
    delete rooms[rid]
    console.log('房间被移除:' + rid)
  }

  //延迟关闭房间
  private DelayCloseRoom(rid: string) {
    console.log('延迟关闭房间!')

    if (!!rooms[rid].closing) {
      console.log('正在延时关闭中.')
      return
    }

    rooms[rid].closing = true

    setTimeout(() => {

      rooms[rid].closing = false

      //如果房间还有人,则不关闭
      let length = Object.keys(rooms[rid].sockets).length
      if (length > 0) {
        console.log('房间还有人,暂时不关闭.')
        return
      }

      rooms[rid].child.kill()
      this._DeleteRoom(rid)
    }, 10000)
  }

  async CheckLauncServer(rid:string)
  {
    let room = rooms[rid]

    if (!room) {
      console.log(`房间:${rid}不存在,不启动服务.`);
      return
    }

    if (!!rooms[rid].closing) {
      console.log('正在延时关闭中.')
      return
    }

    //如果房间有人则启动监听服务.
    if(Object.keys(room.sockets).length > 0)
        this._LaunchServer(rid)
    else
        this.DelayCloseRoom(rid)
  }

  async _LaunchServer(rid: string) {

    let room = rooms[rid]

    if (!room) {
      throw Error('房间号无效.');
    }

    try {

      let opt = {
        env: {
          LISTEN: rid
        }
      }

      console.log('开始进程！！')
      let child = fork("src/app/child_server/server.js", opt)
      room.child = child

      child.on("message", (message, handle) => {
        //console.log("REV")
        //console.log(message)
        //this.ctx.emit('Hello', message)

        for (const k in room.sockets) {
          let ws = room.sockets[k]
          ws.OnMessage(message)
        }
      })

      child.on('exit', () => {

        console.log('子进程退出.')

        setTimeout(()=>{
          console.log('服务进程退出,检查房间是否需要重启服务.')
          this.CheckLauncServer(rid)
        },2000)

        console.log('子进程被干掉!!')
      })

    } catch (error) {
      console.log(error)

      for (const k in room.sockets) {
        let ws = room.sockets[k]
        ws.disconnect()
        delete room.sockets[k]
      }

      //this.DeleteRoom(rid)

      //延时再启动
      setTimeout(()=>{
        console.log('服务进程异常,检查房间是否需要重启服务.')
          this.CheckLauncServer(rid)
      },1000)
    }
  }

  async JoinRoom(rid: string, sid: string, ws: Object) {

    if (!!rooms[rid]) {
      rooms[rid].sockets[sid] = ws
      return
    }

    let room: any = {}
    room.sockets = {}
    room.sockets[sid] = ws
    room.child = null

    rooms[rid] = room

    this.CheckLauncServer(rid)
  }


  async LeaveRoom(rid: string, sid: string) {
    console.log('离开房间:' + rid)
    if (!rooms[rid]) {
      return
    }

    delete rooms[rid].sockets[sid]

    let length = Object.keys(rooms[rid].sockets).length
    if (length == 0)
      this.DelayCloseRoom(rid)
  }


  async SendToProcess(rid: string, message: any) {
    if (!rooms[rid])
      return

    rooms[rid].child?.send(message)
  }
}